/**
 * jQuery.iColor - jQuery Plugin
 *
 * Under The MIT License
 * Copyright (c) 2010 Iwasaki. (http://d.hatena.ne.jp/ja9/)
 * 
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Version: 1.0 beta
 * Revision: $Rev: 2 $
 * Date: $Date: 2010-09-21 06:40:46 +0000 (Tue, 21 Sep 2010) $
 */
(function($) {

  var colorNames = {
        'black'                 : {'r': 0x00, 'g': 0x00, 'b': 0x00, 'type': 'RGB'},
        'navy'                  : {'r': 0x00, 'g': 0x00, 'b': 0x80, 'type': 'RGB'},
        'darkblue'              : {'r': 0x00, 'g': 0x00, 'b': 0x8b, 'type': 'RGB'},
        'mediumblue'            : {'r': 0x00, 'g': 0x00, 'b': 0xcd, 'type': 'RGB'},
        'blue'                  : {'r': 0x00, 'g': 0x00, 'b': 0xff, 'type': 'RGB'},
        'darkgreen'             : {'r': 0x00, 'g': 0x64, 'b': 0x00, 'type': 'RGB'},
        'green'                 : {'r': 0x00, 'g': 0x80, 'b': 0x00, 'type': 'RGB'},
        'teal'                  : {'r': 0x00, 'g': 0x80, 'b': 0x80, 'type': 'RGB'},
        'darkcyan'              : {'r': 0x00, 'g': 0x8b, 'b': 0x8b, 'type': 'RGB'},
        'deepskyblue'           : {'r': 0x00, 'g': 0xbf, 'b': 0xff, 'type': 'RGB'},
        'darkturquoise'         : {'r': 0x00, 'g': 0xce, 'b': 0xd1, 'type': 'RGB'},
        'mediumspringgreen'     : {'r': 0x00, 'g': 0xfa, 'b': 0x9a, 'type': 'RGB'},
        'lime'                  : {'r': 0x00, 'g': 0xff, 'b': 0x00, 'type': 'RGB'},
        'springgreen'           : {'r': 0x00, 'g': 0xff, 'b': 0x7f, 'type': 'RGB'},
        'aqua, cyan'            : {'r': 0x00, 'g': 0xff, 'b': 0xff, 'type': 'RGB'},
        'midnightblue'          : {'r': 0x19, 'g': 0x19, 'b': 0x70, 'type': 'RGB'},
        'dodgerblue'            : {'r': 0x1e, 'g': 0x90, 'b': 0xff, 'type': 'RGB'},
        'lightseagreen'         : {'r': 0x20, 'g': 0xb2, 'b': 0xaa, 'type': 'RGB'},
        'forestgreen'           : {'r': 0x22, 'g': 0x8b, 'b': 0x22, 'type': 'RGB'},
        'seagreen'              : {'r': 0x2e, 'g': 0x8b, 'b': 0x57, 'type': 'RGB'},
        'darkslategray'         : {'r': 0x2f, 'g': 0x4f, 'b': 0x4f, 'type': 'RGB'},
        'darkslategrey'         : {'r': 0x2f, 'g': 0x4f, 'b': 0x4f, 'type': 'RGB'},
        'limegreen'             : {'r': 0x32, 'g': 0xcd, 'b': 0x32, 'type': 'RGB'},
        'mediumseagreen'        : {'r': 0x3c, 'g': 0xb3, 'b': 0x71, 'type': 'RGB'},
        'turquoise'             : {'r': 0x40, 'g': 0xe0, 'b': 0xd0, 'type': 'RGB'},
        'royalblue'             : {'r': 0x41, 'g': 0x69, 'b': 0xe1, 'type': 'RGB'},
        'steelblue'             : {'r': 0x46, 'g': 0x82, 'b': 0xb4, 'type': 'RGB'},
        'darkslateblue'         : {'r': 0x48, 'g': 0x3d, 'b': 0x8b, 'type': 'RGB'},
        'mediumturquoise'       : {'r': 0x48, 'g': 0xd1, 'b': 0xcc, 'type': 'RGB'},
        'indigo'                : {'r': 0x4b, 'g': 0x00, 'b': 0x82, 'type': 'RGB'},
        'darkolivegreen'        : {'r': 0x55, 'g': 0x6b, 'b': 0x2f, 'type': 'RGB'},
        'cadetblue'             : {'r': 0x5f, 'g': 0x9e, 'b': 0xa0, 'type': 'RGB'},
        'cornflowerblue'        : {'r': 0x64, 'g': 0x95, 'b': 0xed, 'type': 'RGB'},
        'mediumaquamarine'      : {'r': 0x66, 'g': 0xcd, 'b': 0xaa, 'type': 'RGB'},
        'dimgray'               : {'r': 0x69, 'g': 0x69, 'b': 0x69, 'type': 'RGB'},
        'dimgrey'               : {'r': 0x69, 'g': 0x69, 'b': 0x69, 'type': 'RGB'},
        'slateblue'             : {'r': 0x6a, 'g': 0x5a, 'b': 0xcd, 'type': 'RGB'},
        'olivedrab'             : {'r': 0x6b, 'g': 0x8e, 'b': 0x23, 'type': 'RGB'},
        'slategray'             : {'r': 0x70, 'g': 0x80, 'b': 0x90, 'type': 'RGB'},
        'slategrey'             : {'r': 0x70, 'g': 0x80, 'b': 0x90, 'type': 'RGB'},
        'lightslategray'        : {'r': 0x77, 'g': 0x88, 'b': 0x99, 'type': 'RGB'},
        'lightslategrey'        : {'r': 0x77, 'g': 0x88, 'b': 0x99, 'type': 'RGB'},
        'mediumslateblue'       : {'r': 0x7b, 'g': 0x68, 'b': 0xee, 'type': 'RGB'},
        'lawngreen'             : {'r': 0x7c, 'g': 0xfc, 'b': 0x00, 'type': 'RGB'},
        'chartreuse'            : {'r': 0x7f, 'g': 0xff, 'b': 0x00, 'type': 'RGB'},
        'aquamarine'            : {'r': 0x7f, 'g': 0xff, 'b': 0xd4, 'type': 'RGB'},
        'maroon'                : {'r': 0x80, 'g': 0x00, 'b': 0x00, 'type': 'RGB'},
        'purple'                : {'r': 0x80, 'g': 0x00, 'b': 0x80, 'type': 'RGB'},
        'olive'                 : {'r': 0x80, 'g': 0x80, 'b': 0x00, 'type': 'RGB'},
        'gray'                  : {'r': 0x80, 'g': 0x80, 'b': 0x80, 'type': 'RGB'},
        'grey'                  : {'r': 0x80, 'g': 0x80, 'b': 0x80, 'type': 'RGB'},
        'skyblue'               : {'r': 0x87, 'g': 0xce, 'b': 0xeb, 'type': 'RGB'},
        'lightskyblue'          : {'r': 0x87, 'g': 0xce, 'b': 0xfa, 'type': 'RGB'},
        'blueviolet'            : {'r': 0x8a, 'g': 0x2b, 'b': 0xe2, 'type': 'RGB'},
        'darkred'               : {'r': 0x8b, 'g': 0x00, 'b': 0x00, 'type': 'RGB'},
        'darkmagenta'           : {'r': 0x8b, 'g': 0x00, 'b': 0x8b, 'type': 'RGB'},
        'saddlebrown'           : {'r': 0x8b, 'g': 0x45, 'b': 0x13, 'type': 'RGB'},
        'darkseagreen'          : {'r': 0x8f, 'g': 0xbc, 'b': 0x8f, 'type': 'RGB'},
        'lightgreen'            : {'r': 0x90, 'g': 0xee, 'b': 0x90, 'type': 'RGB'},
        'mediumpurple'          : {'r': 0x93, 'g': 0x70, 'b': 0xdb, 'type': 'RGB'},
        'darkviolet'            : {'r': 0x94, 'g': 0x00, 'b': 0xd3, 'type': 'RGB'},
        'palegreen'             : {'r': 0x98, 'g': 0xfb, 'b': 0x98, 'type': 'RGB'},
        'darkorchid'            : {'r': 0x99, 'g': 0x32, 'b': 0xcc, 'type': 'RGB'},
        'yellowgreen'           : {'r': 0x9a, 'g': 0xcd, 'b': 0x32, 'type': 'RGB'},
        'sienna'                : {'r': 0xa0, 'g': 0x52, 'b': 0x2d, 'type': 'RGB'},
        'brown'                 : {'r': 0xa5, 'g': 0x2a, 'b': 0x2a, 'type': 'RGB'},
        'darkgray'              : {'r': 0xa9, 'g': 0xa9, 'b': 0xa9, 'type': 'RGB'},
        'darkgrey'              : {'r': 0xa9, 'g': 0xa9, 'b': 0xa9, 'type': 'RGB'},
        'lightblue'             : {'r': 0xad, 'g': 0xd8, 'b': 0xe6, 'type': 'RGB'},
        'greenyellow'           : {'r': 0xad, 'g': 0xff, 'b': 0x2f, 'type': 'RGB'},
        'paleturquoise'         : {'r': 0xaf, 'g': 0xee, 'b': 0xee, 'type': 'RGB'},
        'lightsteelblue'        : {'r': 0xb0, 'g': 0xc4, 'b': 0xde, 'type': 'RGB'},
        'powderblue'            : {'r': 0xb0, 'g': 0xe0, 'b': 0xe6, 'type': 'RGB'},
        'firebrick'             : {'r': 0xb2, 'g': 0x22, 'b': 0x22, 'type': 'RGB'},
        'darkgoldenrod'         : {'r': 0xb8, 'g': 0x86, 'b': 0x0b, 'type': 'RGB'},
        'mediumorchid'          : {'r': 0xba, 'g': 0x55, 'b': 0xd3, 'type': 'RGB'},
        'rosybrown'             : {'r': 0xbc, 'g': 0x8f, 'b': 0x8f, 'type': 'RGB'},
        'darkkhaki'             : {'r': 0xbd, 'g': 0xb7, 'b': 0x6b, 'type': 'RGB'},
        'silver'                : {'r': 0xc0, 'g': 0xc0, 'b': 0xc0, 'type': 'RGB'},
        'mediumvioletred'       : {'r': 0xc7, 'g': 0x15, 'b': 0x85, 'type': 'RGB'},
        'indianred'             : {'r': 0xcd, 'g': 0x5c, 'b': 0x5c, 'type': 'RGB'},
        'peru'                  : {'r': 0xcd, 'g': 0x85, 'b': 0x3f, 'type': 'RGB'},
        'chocolate'             : {'r': 0xd2, 'g': 0x69, 'b': 0x1e, 'type': 'RGB'},
        'tan'                   : {'r': 0xd2, 'g': 0xb4, 'b': 0x8c, 'type': 'RGB'},
        'lightgray'             : {'r': 0xd3, 'g': 0xd3, 'b': 0xd3, 'type': 'RGB'},
        'lightgrey'             : {'r': 0xd3, 'g': 0xd3, 'b': 0xd3, 'type': 'RGB'},
        'thistle'               : {'r': 0xd8, 'g': 0xbf, 'b': 0xd8, 'type': 'RGB'},
        'orchid'                : {'r': 0xda, 'g': 0x70, 'b': 0xd6, 'type': 'RGB'},
        'goldenrod'             : {'r': 0xda, 'g': 0xa5, 'b': 0x20, 'type': 'RGB'},
        'palevioletred'         : {'r': 0xdb, 'g': 0x70, 'b': 0x93, 'type': 'RGB'},
        'crimson'               : {'r': 0xdc, 'g': 0x14, 'b': 0x3c, 'type': 'RGB'},
        'gainsboro'             : {'r': 0xdc, 'g': 0xdc, 'b': 0xdc, 'type': 'RGB'},
        'plum'                  : {'r': 0xdd, 'g': 0xa0, 'b': 0xdd, 'type': 'RGB'},
        'burlywood'             : {'r': 0xde, 'g': 0xb8, 'b': 0x87, 'type': 'RGB'},
        'lightcyan'             : {'r': 0xe0, 'g': 0xff, 'b': 0xff, 'type': 'RGB'},
        'lavender'              : {'r': 0xe6, 'g': 0xe6, 'b': 0xfa, 'type': 'RGB'},
        'darksalmon'            : {'r': 0xe9, 'g': 0x96, 'b': 0x7a, 'type': 'RGB'},
        'violet'                : {'r': 0xee, 'g': 0x82, 'b': 0xee, 'type': 'RGB'},
        'palegoldenrod'         : {'r': 0xee, 'g': 0xe8, 'b': 0xaa, 'type': 'RGB'},
        'lightcoral'            : {'r': 0xf0, 'g': 0x80, 'b': 0x80, 'type': 'RGB'},
        'khaki'                 : {'r': 0xf0, 'g': 0xe6, 'b': 0x8c, 'type': 'RGB'},
        'aliceblue'             : {'r': 0xf0, 'g': 0xf8, 'b': 0xff, 'type': 'RGB'},
        'honeydew'              : {'r': 0xf0, 'g': 0xff, 'b': 0xf0, 'type': 'RGB'},
        'azure'                 : {'r': 0xf0, 'g': 0xff, 'b': 0xff, 'type': 'RGB'},
        'sandybrown'            : {'r': 0xf4, 'g': 0xa4, 'b': 0x60, 'type': 'RGB'},
        'wheat'                 : {'r': 0xf5, 'g': 0xde, 'b': 0xb3, 'type': 'RGB'},
        'beige'                 : {'r': 0xf5, 'g': 0xf5, 'b': 0xdc, 'type': 'RGB'},
        'whitesmoke'            : {'r': 0xf5, 'g': 0xf5, 'b': 0xf5, 'type': 'RGB'},
        'mintcream'             : {'r': 0xf5, 'g': 0xff, 'b': 0xfa, 'type': 'RGB'},
        'ghostwhite'            : {'r': 0xf8, 'g': 0xf8, 'b': 0xff, 'type': 'RGB'},
        'salmon'                : {'r': 0xfa, 'g': 0x80, 'b': 0x72, 'type': 'RGB'},
        'antiquewhite'          : {'r': 0xfa, 'g': 0xeb, 'b': 0xd7, 'type': 'RGB'},
        'linen'                 : {'r': 0xfa, 'g': 0xf0, 'b': 0xe6, 'type': 'RGB'},
        'lightgoldenrodyellow'  : {'r': 0xfa, 'g': 0xfa, 'b': 0xd2, 'type': 'RGB'},
        'oldlace'               : {'r': 0xfd, 'g': 0xf5, 'b': 0xe6, 'type': 'RGB'},
        'red'                   : {'r': 0xff, 'g': 0x00, 'b': 0x00, 'type': 'RGB'},
        'fuchsia'               : {'r': 0xff, 'g': 0x00, 'b': 0xff, 'type': 'RGB'},
        'magenta'               : {'r': 0xff, 'g': 0x00, 'b': 0xff, 'type': 'RGB'},
        'deeppink'              : {'r': 0xff, 'g': 0x14, 'b': 0x93, 'type': 'RGB'},
        'orangered'             : {'r': 0xff, 'g': 0x45, 'b': 0x00, 'type': 'RGB'},
        'tomato'                : {'r': 0xff, 'g': 0x63, 'b': 0x47, 'type': 'RGB'},
        'hotpink'               : {'r': 0xff, 'g': 0x69, 'b': 0xb4, 'type': 'RGB'},
        'coral'                 : {'r': 0xff, 'g': 0x7f, 'b': 0x50, 'type': 'RGB'},
        'darkorange'            : {'r': 0xff, 'g': 0x8c, 'b': 0x00, 'type': 'RGB'},
        'lightsalmon'           : {'r': 0xff, 'g': 0xa0, 'b': 0x7a, 'type': 'RGB'},
        'orange'                : {'r': 0xff, 'g': 0xA5, 'b': 0x00, 'type': 'RGB'},
        'lightpink'             : {'r': 0xff, 'g': 0xb6, 'b': 0xc1, 'type': 'RGB'},
        'pink'                  : {'r': 0xff, 'g': 0xc0, 'b': 0xcb, 'type': 'RGB'},
        'gold'                  : {'r': 0xff, 'g': 0xd7, 'b': 0x00, 'type': 'RGB'},
        'peachpuff'             : {'r': 0xff, 'g': 0xda, 'b': 0xb9, 'type': 'RGB'},
        'navajowhite'           : {'r': 0xff, 'g': 0xde, 'b': 0xad, 'type': 'RGB'},
        'moccasin'              : {'r': 0xff, 'g': 0xe4, 'b': 0xb5, 'type': 'RGB'},
        'bisque'                : {'r': 0xff, 'g': 0xe4, 'b': 0xc4, 'type': 'RGB'},
        'mistyrose'             : {'r': 0xff, 'g': 0xe4, 'b': 0xe1, 'type': 'RGB'},
        'blanchedalmond'        : {'r': 0xff, 'g': 0xeb, 'b': 0xcd, 'type': 'RGB'},
        'papayawhip'            : {'r': 0xff, 'g': 0xef, 'b': 0xd5, 'type': 'RGB'},
        'lavenderblush'         : {'r': 0xff, 'g': 0xf0, 'b': 0xf5, 'type': 'RGB'},
        'seashell'              : {'r': 0xff, 'g': 0xf5, 'b': 0xee, 'type': 'RGB'},
        'cornsilk'              : {'r': 0xff, 'g': 0xf8, 'b': 0xdc, 'type': 'RGB'},
        'lemonchiffon'          : {'r': 0xff, 'g': 0xfa, 'b': 0xcd, 'type': 'RGB'},
        'floralwhite'           : {'r': 0xff, 'g': 0xfa, 'b': 0xf0, 'type': 'RGB'},
        'snow'                  : {'r': 0xff, 'g': 0xfa, 'b': 0xfa, 'type': 'RGB'},
        'yellow'                : {'r': 0xff, 'g': 0xff, 'b': 0x00, 'type': 'RGB'},
        'lightyellow'           : {'r': 0xff, 'g': 0xff, 'b': 0xe0, 'type': 'RGB'},
        'ivory'                 : {'r': 0xff, 'g': 0xff, 'b': 0xf0, 'type': 'RGB'},
        'white'                 : {'r': 0xff, 'g': 0xff, 'b': 0xff, 'type': 'RGB'}
      },

      iColor = function(a, b, c, d, e) {
        return new iColor.fn.init(a, b, c, d, e);
      },

      iColorOperation = {
        RGBtoHSV: function(r, g, b, a) {
          var h, // 0..360
              s, v; // 0..1

          // 0..1 に変換
          r = r / 255;
          g = g / 255;
          b = b / 255;
          var max = Math.max(Math.max(r, g), b),
              min = Math.min(Math.min(r, g), b);

          // hue の計算
          if (max == min) {
            h = 0; // 本来は定義されないが、仮に0を代入
          } else if (max == r) {
            h = 60 * (g - b) / (max - min) + 0;
          } else if (max == g) {
            h = (60 * (b - r) / (max - min)) + 120;
          } else {
            h = (60 * (r - g) / (max - min)) + 240;
          }

          while (h < 0) {
            h += 360;
          }

          // saturation の計算
          s = (max == 0)
            ? 0 // 本来は定義されないが、仮に0を代入
            : (max - min) / max;

          // value の計算
          v = max;

          return (typeof(a) == "undefined")
            ? iColor({'h': h, 's': s, 'v': v, 'type': 'HSV'})
            : iColor({'h': h, 's': s, 'v': v, 'a': a, 'type': 'HSVA'})
        },

        HSVtoRGB: function(h, s, v, a) {
          var r, g, b; // 0..255

          while (h < 0) {
            h += 360;
          }
          h = h % 360;

          // 特別な場合 saturation = 0
          if (s == 0) {
            // → RGB は V に等しい
            v = v * 255;
            return (typeof(a) == "undefined")
              ? iColor({'r': v, 'g': v, 'b': v, 'type': 'RGB'})
              : iColor({'r': v, 'g': v, 'b': v, 'a': a, 'type': 'RGBA'});
          }

          var i = Math.floor(h / 60) % 6,
              f = (h / 60) - i,
              p = v * (1 - s),
              q = v * (1 - f * s),
              t = v * (1 - (1 - f) * s)

          switch (i) {
            case 0 :
              r = v;  g = t;  b = p;  break;
            case 1 :
              r = q;  g = v;  b = p;  break;
            case 2 :
              r = p;  g = v;  b = t;  break;
            case 3 :
              r = p;  g = q;  b = v;  break;
            case 4 :
              r = t;  g = p;  b = v;  break;
            case 5 :
              r = v;  g = p;  b = q;  break;
          }

          return (typeof(a) == "undefined")
            ? iColor({'r': r * 255, 'g': g * 255, 'b': b * 255, 'type': 'RGB'})
            : iColor({'r': r * 255, 'g': g * 255, 'b': b * 255, 'a': a, 'type': 'RGBA'});
        },

        RGBtoHLS: function(r, g, b, a) {
          var h, // 0..360
              l, s; // 0..1

          // 0..1 に変換
          r = r / 255;
          g = g / 255;
          b = b / 255;
          var max = Math.max(Math.max(r, g), b),
              min = Math.min(Math.min(r, g), b);

          // hue の計算
          if (max == min) {
            h = 0; // 本来は定義されないが、仮に0を代入
          } else if (max == r) {
            h = 60 * (g - b) / (max - min) + 0;
          } else if (max == g) {
            h = (60 * (b - r) / (max - min)) + 120;
          } else {
            h = (60 * (r - g) / (max - min)) + 240;
          }

          while (h < 0) {
            h += 360;
          }

          // Lightness の計算
          l = (max + min) / 2;

          // Saturation の計算
          if (max == min) {
            s = 0;
          } else {
            s = (l < 0.5)
              ? (max - min) / (max + min)
              : (max - min) / (2.0 - max - min);
          }

          return (typeof(a) == "undefined")
            ? iColor({'h': h, 'l': l, 's': s, 'type': 'HLS'})
            : iColor({'h': h, 'l': l, 's': s, 'a': a,'type': 'HLSA'});
        },

        HLStoRGB: function(h, l, s, a) {
          var r, g, b; // 0..255

          while (h < 0) {
            h += 360;
          }
          h = h % 360;

          // 特別な場合 saturation = 0
          if (s == 0) {
            // → RGB は V に等しい
            l = l * 255;
            return (typeof(a) == "undefined")
              ? iColor({'r': l, 'g': l, 'b': l, 'type': 'RGB'})
              : iColor({'r': l, 'g': l, 'b': l, 'a': a, 'type': 'RGBA'});
          }

          var m2 = (l < 0.5) ? l * (1 + s) : l + s - l * s,
              m1 = l * 2 - m2,
              tmp;

          tmp = h + 120;
          if (tmp > 360) {
            tmp = tmp - 360
          }

          if (tmp < 60) {
            r = (m1 + (m2 - m1) * tmp / 60);
          } else if (tmp < 180) {
            r = m2;
          } else if (tmp < 240) {
            r = m1 + (m2 - m1) * (240 - tmp) / 60;
          } else {
            r = m1;
          }

          tmp = h;
          if (tmp < 60) {
            g = m1 + (m2 - m1) * tmp / 60;
          } else if (tmp < 180) {
            g = m2;
          } else if (tmp < 240) {
            g = m1 + (m2 - m1) * (240 - tmp) / 60;
          } else {
            g = m1;
          }

          tmp = h - 120;
          if (tmp < 0) {
            tmp = tmp + 360
          }
          if (tmp < 60) {
            b = m1 + (m2 - m1) * tmp / 60;
          } else if (tmp < 180) {
            b = m2;
          } else if (tmp < 240) {
            b = m1 + (m2 - m1) * (240 - tmp) / 60;
          } else {
            b = m1;
          }

          return (typeof(a) == "undefined")
            ? iColor({'r': r * 255, 'g': g * 255, 'b': b * 255, 'type': 'RGB'})
            : iColor({'r': r * 255, 'g': g * 255, 'b': b * 255, 'a': a, 'type': 'RGBA'});
        },

        range: function(target, max, isAngle, round) {
          target = target || '';
          max = max || 255;

          if (typeof target != "number") {
            target = target.replace(/\s/g, '');

            if (!isNaN(target)) {
              target = Number(target);
            } else if (target.charAt(target.length - 1) == '%'
              && !isNaN(target.substr(0, target.length - 1))) {

              var tmp = Number(target.substr(0, target.length - 1)) / 100;
              target = max * tmp;
            } else {
              // default value
              target = 0;
            }
          }

          if (round) {
            target = Math.round(target)
          }

          if (isAngle) {
            while (target < 0) {
              target = target + max;
            }

            target = target % max;
          }

          if (target < 0) {
            return 0;
          } else if (target > max) {
            return max;
          }

          return target;
        }

      };

  iColor.fn = iColor.prototype = $.extend(iColor.prototype, {
    init: function(a, b, c, d, e) {
      var arr;

      if (isVal(a) && isVal(b) && isVal(c)) {
        // 引数1～3が全て数値なら
        arr = [a, b, c];

        if (isVal(d)) {
          // 引数4も数値なら init(255, 127, 0, 0.7, 'RGBA')
          arr.push(d);
          this.type = type(e, true);
        } else {
          // 引数4が数値以外 init(255, 127, 0, 'RGB')
          this.type = type(d);
        }
      } else if (Object.prototype.toString.call(a) == '[object Array]') {
        // 配列なら init([255, 127, 0], 'RGB')
        arr = a;
        this.type = type(b, (a.length >= 4));
      } else if (Object.prototype.toString.call(a) == '[object Object]') {
        // オブジェクトの場合.
        this.type = type(a.type || b);
        arr = [
            a[this.type.charAt(0).toLowerCase()],
            a[this.type.charAt(1).toLowerCase()],
            a[this.type.charAt(2).toLowerCase()]
          ];
        if (this.type.length >= 4 || typeof(a.a) != "undefined") {
          arr.push(a.a);
        }
      } else {
        // 文字列？
        a = a.replace(/\s/g, '').toLowerCase(); // スペース削除
        if (a.charAt(0) == '#' && !a.substr(1).match(/[^0-9a-f]/)) {
          // #rrggbb
          // #rgb
          a = a.substr(1);
          this.type = type('RGB');
          switch (a.length) {
            case 3:
              a = a.charAt(0) + a.charAt(0) + a.charAt(1) + a.charAt(1) + a.charAt(2) + a.charAt(2);
            case 6:
              arr = [
                  parseInt(a.substr(0, 2), 16),
                  parseInt(a.substr(2, 2), 16),
                  parseInt(a.substr(4, 2), 16)
                ];
            break;
          }
        } else if (!!a.match(/^(rgb|hsl)a?\([0-9.]+%?,[0-9.]+%?,[0-9.]+%?(,[0-9.]+%?)?\)/)) {
          // rgb ([0-255], [0-255], [0-255]) or rgb ([0-100]%, [0-100]%, [0-100]%)
          // rgba([0-255], [0-255], [0-255], [0-1]) or rgba([0-100]%, [0-100]%, [0-100]%, [0-1])
          // hsl ([0-360], [0-100]%, [0-100]%) or hsla([0-360], [0-100]%, [0-100]%, [0-1])
          var tmp = a.indexOf('(');
          this.type = type(a.substr(0, tmp));
          arr = a.substr(tmp + 1, a.indexOf(')') - tmp - 1).split(',');
        } else if (Object.prototype.toString.call(colorNames[a]) == '[object Object]') {
          // colornames
          return iColor(colorNames[a]);
        } else {
          this.type = type('RGB');
        }
      }

      for (var i = 0; i < this.type.length; i++) {
        var tmp = arr[i];

        switch (this.type[i]) {
          case 'R':
          case 'G':
          case 'B':
            tmp = iColorOperation.range(tmp, 255);
            break;

          case 'H':
            tmp = iColorOperation.range(tmp, 360, true);
            break;

          case 'L':
          case 'S':
          case 'V':
          case 'A':
            tmp = iColorOperation.range(tmp, 1);
            break;
        }

        this[this.type.charAt(i).toLowerCase()] = tmp;
      }

      return this;

      function isVal(target) {
        // number型、もしくはnumericか
        if (typeof target == "number") {
          return true;
        }

        if (typeof target != "string") {
          return false;
        }

        target = target.replace(/\s/g, '');

        if (target == '') {
          return false;
        }

        if (!isNaN(target)) {
          return true;
        }

        return (target.charAt(target.length - 1) == '%'
          && !isNaN(target.substr(0, target.length - 1)));
      }

      function type(str, defaultUseAlpha) {
        str = str || '';

        switch (str.toUpperCase()) {
          case 'HLS':
          case 'HSL':
          case 'HSV':
          case 'RGB':

          case 'HLSA':
          case 'HSLA':
          case 'HSVA':
          case 'RGBA':
            return str.toUpperCase();
            break;
          default:
            return (defaultUseAlpha) ? 'RGBA' : 'RGB';
            break;
        }
      }
    },
    getStr: function(format) {
      var tmp, arr = [];
      var isMSIE = (window.navigator.userAgent.toLowerCase().indexOf("msie") >= 0);
      format = (format || '#xxx').toLowerCase();

      switch (format.substr(0,3)) {
        case 'rgb':
          tmp = this.toRGB();

          if (format.indexOf('%') > 0) {
            arr.push(iColorOperation.range((tmp.r / 255) * 100, 100, false, true) + '%');
            arr.push(iColorOperation.range((tmp.g / 255) * 100, 100, false, true) + '%');
            arr.push(iColorOperation.range((tmp.b / 255) * 100, 100, false, true) + '%');
          } else {
            arr.push(iColorOperation.range(tmp.r, 255, false, true));
            arr.push(iColorOperation.range(tmp.g, 255, false, true));
            arr.push(iColorOperation.range(tmp.b, 255, false, true));
          }

          if (!isMSIE && (typeof tmp.a == "number" || (typeof tmp.a == "string" && tmp.a != ''))) {
            arr.push(iColorOperation.range(tmp.a, 1));
            return 'rgba(' + arr.join(', ') + ')';
          }

          return 'rgb(' + arr.join(', ') + ')';
          break;
        case 'hsl':
          tmp = this.toHSL();

          arr.push(iColorOperation.range(tmp.h, 360, true, true));
          arr.push(iColorOperation.range(tmp.s * 100, 100, false, true) + '%');
          arr.push(iColorOperation.range(tmp.l * 100, 100, false, true) + '%');

          if (typeof tmp.a == "number" || (typeof tmp.a == "string" && tmp.a != '')) {
            arr.push(iColorOperation.range(tmp.a, 1));
            return 'hsla(' + arr.join(', ') + ')';
          }

          return 'hsl(' + arr.join(', ') + ')';
          break;
        case '#':
        case '#xx':
        default:

          var str = '';
          tmp = this.toRGB();

          arr.push(iColorOperation.range(tmp.r, 255, false, true).toString(16));
          arr.push(iColorOperation.range(tmp.g, 255, false, true).toString(16));
          arr.push(iColorOperation.range(tmp.b, 255, false, true).toString(16));

          for (var i=0; i<arr.length; i++) {
            str += (arr[i].length == 1) ? '0' + arr[i] : arr[i];
          }

          if (format.length <= 4 && str.charAt(0) == str.charAt(1) && str.charAt(2) == str.charAt(3) && str.charAt(4) == str.charAt(5)) {
            str = str.charAt(0) + str.charAt(2) + str.charAt(4);
          }

          return '#' + str;
          break;
      }
    },
    to: function(toType) {
      var fromType = this.type.toUpperCase().substr(0, 3);
      toType = toType.toUpperCase().substr(0, 3);
      if (fromType == toType) {
        return iColor(this);
      }

      switch (toType) {
        case 'RGB':
          if (fromType == 'HSV') {
            return iColorOperation.HSVtoRGB(this.h, this.s, this.v, this.a);
          } else if (fromType == 'HLS' || fromType == 'HSL') {
            return iColorOperation.HLStoRGB(this.h, this.l, this.s, this.a);
          }
          break;

        case 'HSV':
          return iColorOperation.RGBtoHSV(this.toRGB().r, this.toRGB().g, this.toRGB().b, this.toRGB().a);
          break;

        case 'HLS':
        case 'HSL':
          var tmp = iColorOperation.RGBtoHLS(this.toRGB().r, this.toRGB().g, this.toRGB().b, this.toRGB().a);

          if (toType == 'HLS') {
            return tmp;
          }

          return (typeof(tmp.a) == "undefined")
            ? iColor({'h': tmp.h, 's': tmp.s, 'l': tmp.l, 'type': 'HSL'})
            : iColor({'h': tmp.h, 's': tmp.s, 'l': tmp.l, 'a': tmp.a, 'type': 'HSLA'});
          break;
      }

      return this;
    },
    toRGB: function() {
      return this.to('RGB');
    },
    toRGBA: function() {
      return this.to('RGB');
    },
    toHSV: function() {
      return this.to('HSV');
    },
    toHSVA: function() {
      return this.to('HSV');
    },
    toHSL: function() {
      return this.to('HSL');
    },
    toHSLA: function() {
      return this.to('HSL');
    },
    toHLS: function() {
      return this.to('HLS');
    },
    toHLSA: function() {
      return this.to('HLS');
    },
    change: function(target, val, mode) {
      mode = (mode || this.type).toUpperCase().substr(0, 3);
      val = val || 0;
      target = target.charAt(0).toUpperCase();

      switch (mode) {
        case 'RGB':
        case 'HSV':
        case 'HLS':
        case 'HSL':
          if (mode.indexOf(target) >= 0) {
            break;
          }
        default:
          switch (target) {
            case 'R':
            case 'G':
            case 'B':
              mode = 'RGB';
              break;

            case 'V':
              mode = 'HSV';
              break;

            case 'H':
            case 'L':
            case 'S':
              mode = 'HLS';
              break;
          }
          break;
      }

      var tmp = this.to(mode);

      if (typeof(tmp[target.toLowerCase()]) != "undefined") {
        if (typeof val == "number") {
          tmp[target.toLowerCase()] = val;
        } else if (typeof val == "string") {
          val = val.replace(/\s/g, '');

          if (val.indexOf('+=') == 0) {
            tmp[target.toLowerCase()] += Number(val.substr(2));
          } else if (val.indexOf('-=') == 0) {
            tmp[target.toLowerCase()] -= Number(val.substr(2));
          } else {
            tmp[target.toLowerCase()] = Number(val);
          }
        } else {
          return this;
        }

        return tmp.to(this.type);
      }

      return this;
    }
  });

  iColor.fn.init.prototype = iColor.fn;
  $.iColor = iColor;

  $.fn.getColor = function(attr) {
    var target = $(this).eq(0),
        color = target.css(attr);

    if (color == ''
      || color == 'transparent'
      || color == 'inherit'
      || color == 'currentcolor') {
      // 色名が取得出来ない場合

      if (target.is('html, body')
        || target.parent().size() == 0) {

        // html か body エレメントまで辿ったか、
        // もしくは親エレメントが無ければ
        return false;
      }

      // 色が透明の場合は、背景色を見る
      if (color == 'transparent'
        && attr != 'background-color') {
        return target.getColor('background-color');
      } else if (color == 'currentcolor'
        && attr != 'color') {
        return target.getColor('color');
      }

      // 親を見る
      return target.parent().eq(0).getColor(attr);
    }

    return iColor(color);
  };

  $.each([
    'color',
    'backgroundColor',
    'borderTopColor',
    'borderRightColor',
    'borderBottomColor',
    'borderLeftColor',
    'outlineColor'
  ], function(i, attr){
    $.fx.step[attr] = function(fx) {
      if (fx.state == 0 || !fx.end.type) {
        fx.start = $(fx.elem).getColor(attr).toRGB();

        if (Object.prototype.toString.call(fx.end) == '[object Object]') {
          var tmp = fx.start;
          $.each(['r', 'g', 'b', 'v', 'l', 's', 'a'], function(i, s) {
            if (typeof(fx.end[s]) != "undefined") {
              tmp = tmp.change(s, fx.end[s], fx.end.mode);
            }
          });

          if (typeof(fx.end.h) == "undefined") {
            fx.end = tmp.toRGB();
          } else {
            tmp = tmp.toHLS();

            if (typeof fx.end.h == "number") {
              tmp.h = fx.end.h;
            } else if (typeof fx.end.h == "string") {
              fx.end.h = fx.end.h.replace(/\s/g, '');

              if (fx.end.h.indexOf('+=') == 0) {
                tmp.h += Number(fx.end.h.substr(2));
              } else if (fx.end.h.indexOf('-=') == 0) {
                tmp.h -= Number(fx.end.h.substr(2));
              } else {
                tmp.h = Number(fx.end.h);
              }
            }

            fx.start = fx.start.toHLS();
            fx.end = tmp;
          }
        } else {
          fx.end = iColor(fx.end).toRGB();
        }

        if (typeof(fx.start.a) == "undefined") {
          fx.start.a = 1;
        }

        if (typeof(fx.end.a) == "undefined") {
          fx.end.a = fx.start.a;
        }
      }

      if (fx.end.type.substr(0, 3) == 'HLS') {
        fx.elem.style[attr] =
          iColor({
            'h': fx.pos * (fx.end.h - fx.start.h) + fx.start.h,
            'l': fx.pos * (fx.end.l - fx.start.l) + fx.start.l,
            's': fx.pos * (fx.end.s - fx.start.s) + fx.start.s,
            'a': fx.pos * (fx.end.a - fx.start.a) + fx.start.a,
            'type': 'HLSA'
          }).getStr('rgb');
      } else {
        fx.elem.style[attr] =
          iColor({
            'r': fx.pos * (fx.end.r - fx.start.r) + fx.start.r,
            'g': fx.pos * (fx.end.g - fx.start.g) + fx.start.g,
            'b': fx.pos * (fx.end.b - fx.start.b) + fx.start.b,
            'a': fx.pos * (fx.end.a - fx.start.a) + fx.start.a,
            'type': 'RGBA'
          }).getStr('rgb');
      }
    };
  });

})(jQuery);
